<template>
  <div class="receivable-payable-tree">
    <div class="page-container">
      <!-- 页面标题和操作区域 -->
      <div class="page-header">
        <div class="header-content">
          <h1 class="page-title">应收应付明细统计</h1>
          <div class="header-actions">
            <a-range-picker
              v-model="dateRange"
              format="YYYY-MM-DD"
              :placeholder="['开始日期', '结束日期']"
              @change="onDateRangeChange"
              :allowClear="true"
              style="width: 240px; margin-right: 12px"
            />
            <a-button type="primary" @click="refreshData" :loading="loading">
              <a-icon type="reload" />
              刷新数据
            </a-button>
            <a-button @click="exportData" :loading="exportLoading">
              <a-icon type="download" />
              导出数据
            </a-button>
          </div>
        </div>
      </div>

      <!-- 汇总统计卡片 -->
      <div class="summary-cards">
        <div class="summary-card receivable">
          <div class="card-icon">
            <a-icon type="rise" />
          </div>
          <div class="card-content">
            <div class="card-title">应收账款总额</div>
            <div class="card-value">¥{{ formatNumber(summaryData.totalReceivableAmount) }}</div>
            <div class="card-detail">
              已收: ¥{{ formatNumber(summaryData.totalReceivedAmount) }} | 未收: ¥{{
                formatNumber(summaryData.totalUnreceivedAmount)
              }}
            </div>
          </div>
        </div>

        <div class="summary-card payable">
          <div class="card-icon">
            <a-icon type="fall" />
          </div>
          <div class="card-content">
            <div class="card-title">应付账款总额</div>
            <div class="card-value">¥{{ formatNumber(summaryData.totalPayableAmount) }}</div>
            <div class="card-detail">
              已付: ¥{{ formatNumber(summaryData.totalPaidAmount) }} | 未付: ¥{{
                formatNumber(summaryData.totalUnpaidAmount)
              }}
            </div>
          </div>
        </div>

        <div class="summary-card balance">
          <div class="card-icon">
            <a-icon type="swap" />
          </div>
          <div class="card-content">
            <div class="card-title">净资金流</div>
            <div class="card-value" :class="getBalanceClass()">¥{{ formatNumber(getNetCashFlow()) }}</div>
            <div class="card-detail">应收 - 应付 = 净流入/流出</div>
          </div>
        </div>
      </div>

      <!-- 标签页切换 -->
      <div class="content-tabs">
        <a-tabs v-model="activeTab" @change="onTabChange">
          <a-tab-pane key="receivable" tab="应收账款明细">
            <div class="tree-table-container">
              <div class="table-header">
                <h3>应收账款树形明细（客户 → 工程 → 订单）</h3>
                <div class="table-actions">
                  <a-button @click="expandAllReceivable" size="small">
                    <a-icon type="plus-square" />
                    全部展开
                  </a-button>
                  <a-button @click="collapseAllReceivable" size="small">
                    <a-icon type="minus-square" />
                    全部收起
                  </a-button>
                </div>
              </div>

              <a-table
                ref="receivableTable"
                :columns="receivableColumns"
                :data-source="receivableTreeData"
                :loading="loading"
                :pagination="false"
                :scroll="{ x: 1200 }"
                :row-key="(record) => record.id"
                :default-expand-all-rows="false"
                :expand-row-by-click="true"
                :expanded-row-keys="receivableExpandedRowKeys"
                @expand="onReceivableExpand"
                :child-row-key="(record) => record.children"
                size="middle"
                bordered
              >
                <template slot="name" slot-scope="text, record">
                  <span :class="getNodeTypeClass(record.node_type)">
                    <a-icon :type="getNodeIcon(record.node_type)" />
                    {{ text }}
                  </span>
                </template>

                <template slot="totalReceivable" slot-scope="text">
                  <span class="amount-text receivable">¥{{ formatNumber(text) }}</span>
                </template>

                <template slot="totalReceived" slot-scope="text">
                  <span class="amount-text received">¥{{ formatNumber(text) }}</span>
                </template>

                <template slot="totalUnreceived" slot-scope="text">
                  <span class="amount-text unreceived">¥{{ formatNumber(text) }}</span>
                </template>

                <template slot="orderStatus" slot-scope="text">
                  <a-tag v-if="text" :color="getOrderStatusColor(text)">
                    {{ getOrderStatusText(text) }}
                  </a-tag>
                </template>
              </a-table>
            </div>
          </a-tab-pane>

          <a-tab-pane key="payable" tab="应付账款明细">
            <div class="tree-table-container">
              <div class="table-header">
                <h3>应付账款树形明细（供应商 → 采购单 → 采购明细）</h3>
                <div class="table-actions">
                  <a-button @click="expandAllPayable" size="small">
                    <a-icon type="plus-square" />
                    全部展开
                  </a-button>
                  <a-button @click="collapseAllPayable" size="small">
                    <a-icon type="minus-square" />
                    全部收起
                  </a-button>
                </div>
              </div>

              <a-table
                ref="payableTable"
                :columns="payableColumns"
                :data-source="payableTreeData"
                :loading="loading"
                :pagination="false"
                :row-key="(record) => record.id"
                :default-expand-all-rows="false"
                :expand-row-by-click="true"
                :expanded-row-keys="payableExpandedRowKeys"
                @expand="onPayableExpand"
                :child-row-key="(record) => record.children"
                size="middle"
                bordered
              >
                <template slot="name" slot-scope="text, record">
                  <span :class="getNodeTypeClass(record.node_type)">
                    <a-icon :type="getNodeIcon(record.node_type)" />
                    {{ text }}
                  </span>
                </template>

                <template slot="totalPayable" slot-scope="text">
                  <span class="amount-text payable">¥{{ formatNumber(text) }}</span>
                </template>

                <template slot="quantity" slot-scope="text">
                  <span v-if="text">{{ text }}</span>
                </template>

                <template slot="unitPrice" slot-scope="text">
                  <span v-if="text" class="amount-text">¥{{ formatNumber(text) }}</span>
                </template>

                <template slot="amount" slot-scope="text">
                  <span v-if="text" class="amount-text payable">¥{{ formatNumber(text) }}</span>
                </template>
              </a-table>
            </div>
          </a-tab-pane>
        </a-tabs>
      </div>
    </div>
  </div>
</template>

<script>
import { getAction } from '@/api/manage'
import moment from 'moment'

export default {
  name: 'ReceivablePayableTree',
  data() {
    return {
      loading: false,
      exportLoading: false,
      dateRange: [moment().startOf('year'), moment().endOf('year')],
      activeTab: 'receivable',

      // 汇总数据
      summaryData: {
        totalReceivableAmount: 0,
        totalReceivedAmount: 0,
        totalUnreceivedAmount: 0,
        totalPayableAmount: 0,
        totalPaidAmount: 0,
        totalUnpaidAmount: 0,
      },

      // 树形数据
      receivableTreeData: [],
      payableTreeData: [],

      // 展开状态控制
      receivableExpandedRowKeys: [],
      payableExpandedRowKeys: [],

      // 应收账款表格列定义
      receivableColumns: [
        {
          title: '名称',
          dataIndex: 'name',
          key: 'name',
          width: 300,
          scopedSlots: { customRender: 'name' },
        },
        {
          title: '应收金额',
          dataIndex: 'total_receivable',
          key: 'total_receivable',
          width: 120,
          align: 'right',
          scopedSlots: { customRender: 'totalReceivable' },
        },
        {
          title: '已收金额',
          dataIndex: 'total_received',
          key: 'total_received',
          width: 120,
          align: 'right',
          scopedSlots: { customRender: 'totalReceived' },
        },
        {
          title: '未收金额',
          dataIndex: 'total_unreceived',
          key: 'total_unreceived',
          width: 120,
          align: 'right',
          scopedSlots: { customRender: 'totalUnreceived' },
        },
      ],

      // 应付账款表格列定义
      payableColumns: [
        {
          title: '名称',
          dataIndex: 'name',
          key: 'name',
          width: 300,
          scopedSlots: { customRender: 'name' },
        },
        {
          title: '应付金额',
          dataIndex: 'total_payable',
          key: 'total_payable',
          width: 120,
          align: 'right',
          scopedSlots: { customRender: 'totalPayable' },
        },
      ],
    }
  },

  mounted() {
    this.loadData()
  },

  methods: {
    async loadData() {
      this.loading = true
      try {
        await Promise.all([this.loadSummaryData(), this.loadReceivableTreeData(), this.loadPayableTreeData()])
      } catch (error) {
        console.error('加载数据失败:', error)
        this.$message.error('加载数据失败')
      } finally {
        this.loading = false
      }
    },

    async loadSummaryData() {
      const params = this.getDateParams()
      const res = await getAction('/statistics/finance/receivable-payable/summary', params)
      if (res.success && res.result) {
        this.summaryData = {
          totalReceivableAmount: res.result.total_receivable_amount || 0,
          totalReceivedAmount: res.result.total_received_amount || 0,
          totalUnreceivedAmount: res.result.total_unreceived_amount || 0,
          totalPayableAmount: res.result.total_payable_amount || 0,
          totalPaidAmount: res.result.total_paid_amount || 0,
          totalUnpaidAmount: res.result.total_unpaid_amount || 0,
        }
      }
    },

    async loadReceivableTreeData() {
      const params = this.getDateParams()
      console.log('Loading receivable tree data with params:', params)
      const res = await getAction('/statistics/finance/receivable/tree', params)
      console.log('Receivable API response:', res)
      if (res.success && res.result) {
        console.log('Raw receivable data:', res.result)
        // 映射字段名以匹配表格列定义
        const mappedData = res.result.map((item) => ({
          ...item,
          total_receivable: item.total_amount,
          total_received: item.paid_amount,
          total_unreceived: item.unpaid_amount,
          node_type: item.type,
        }))
        console.log('Mapped receivable data:', mappedData)
        this.receivableTreeData = this.buildTreeStructure(mappedData)
        console.log('Final receivable tree data:', this.receivableTreeData)
      } else {
        console.log('No receivable data or API failed:', res)
        this.receivableTreeData = []
      }
    },

    async loadPayableTreeData() {
      const params = this.getDateParams()
      console.log('Loading payable tree data with params:', params)
      const res = await getAction('/statistics/finance/payable/tree', params)
      console.log('Payable API response:', res)
      if (res.success && res.result) {
        console.log('Raw payable data:', res.result)
        // 映射字段名以匹配表格列定义
        const mappedData = res.result.map((item) => ({
          ...item,
          total_payable: item.total_amount,
          total_paid: item.paid_amount,
          total_unpaid: item.unpaid_amount,
          node_type: item.type,
        }))
        console.log('Mapped payable data:', mappedData)
        this.payableTreeData = this.buildTreeStructure(mappedData)
        console.log('Final payable tree data:', this.payableTreeData)
      } else {
        console.log('No payable data or API failed:', res)
        this.payableTreeData = []
      }
    },

    buildTreeStructure(flatData) {
      const tree = []
      const nodeMap = new Map()

      // 先创建所有节点的映射
      flatData.forEach((item) => {
        const node = { ...item, children: [] }
        nodeMap.set(item.id, node)
      })

      // 构建树结构
      flatData.forEach((item) => {
        const node = nodeMap.get(item.id)

        if (!item.parent_id) {
          // 根节点（没有parent_id的节点）
          tree.push(node)
        } else {
          // 子节点，添加到父节点的children中
          const parent = nodeMap.get(item.parent_id)
          if (parent) {
            parent.children.push(node)
          } else {
            // 如果找不到父节点，也作为根节点处理
            tree.push(node)
          }
        }
      })

      return tree
    },

    onDateRangeChange() {
      this.refreshData()
    },

    onTabChange(activeKey) {
      this.activeTab = activeKey
    },

    async refreshData() {
      await this.loadData()
    },

    // 应收账款展开/收起控制
    expandAllReceivable() {
      const allKeys = this.getAllNodeKeys(this.receivableTreeData)
      this.receivableExpandedRowKeys = allKeys
      this.$message.success('已展开所有应收账款节点')
    },

    collapseAllReceivable() {
      this.receivableExpandedRowKeys = []
      this.$message.success('已收起所有应收账款节点')
    },

    onReceivableExpand(expanded, record) {
      const key = record.id
      if (expanded) {
        // 展开节点
        if (!this.receivableExpandedRowKeys.includes(key)) {
          this.receivableExpandedRowKeys.push(key)
        }
      } else {
        // 收起节点
        const index = this.receivableExpandedRowKeys.indexOf(key)
        if (index > -1) {
          this.receivableExpandedRowKeys.splice(index, 1)
        }
      }
    },

    // 应付账款展开/收起控制
    expandAllPayable() {
      const allKeys = this.getAllNodeKeys(this.payableTreeData)
      this.payableExpandedRowKeys = allKeys
      this.$message.success('已展开所有应付账款节点')
    },

    collapseAllPayable() {
      this.payableExpandedRowKeys = []
      this.$message.success('已收起所有应付账款节点')
    },

    onPayableExpand(expanded, record) {
      const key = record.id
      if (expanded) {
        // 展开节点
        if (!this.payableExpandedRowKeys.includes(key)) {
          this.payableExpandedRowKeys.push(key)
        }
      } else {
        // 收起节点
        const index = this.payableExpandedRowKeys.indexOf(key)
        if (index > -1) {
          this.payableExpandedRowKeys.splice(index, 1)
        }
      }
    },

    // 获取所有节点的key（用于全部展开）
    getAllNodeKeys(treeData) {
      const keys = []
      const traverse = (nodes) => {
        nodes.forEach(node => {
          if (node.children && node.children.length > 0) {
            keys.push(node.id)
            traverse(node.children)
          }
        })
      }
      traverse(treeData)
      return keys
    },

    getDateParams() {
      const params = {}
      if (this.dateRange && this.dateRange.length === 2) {
        params.startDate = this.dateRange[0].format('YYYY-MM-DD')
        params.endDate = this.dateRange[1].format('YYYY-MM-DD')
      }
      return params
    },

    formatNumber(num) {
      if (!num) return '0'
      if (num >= 10000) {
        return (num / 10000).toFixed(1) + '万'
      }
      return num.toLocaleString()
    },

    getNetCashFlow() {
      return this.summaryData.totalReceivableAmount - this.summaryData.totalPayableAmount
    },

    getBalanceClass() {
      const netFlow = this.getNetCashFlow()
      if (netFlow > 0) return 'positive'
      if (netFlow < 0) return 'negative'
      return 'neutral'
    },

    getNodeTypeClass(nodeType) {
      return `node-${nodeType}`
    },

    getNodeIcon(nodeType) {
      const iconMap = {
        customer: 'user',
        project: 'project',
        order: 'file-text',
        supplier: 'shop',
        purchase_order: 'shopping-cart',
        purchase_detail: 'unordered-list',
      }
      return iconMap[nodeType] || 'folder'
    },

    getOrderStatusColor(status) {
      const colorMap = {
        draft: 'default',
        pending: 'orange',
        approved: 'blue',
        completed: 'green',
        cancelled: 'red',
      }
      return colorMap[status] || 'default'
    },

    getOrderStatusText(status) {
      const textMap = {
        draft: '草稿',
        pending: '待审核',
        approved: '已审核',
        completed: '已完成',
        cancelled: '已取消',
      }
      return textMap[status] || status
    },

    async exportData() {
      this.exportLoading = true
      try {
        const params = this.getDateParams()

        // 使用axios发送请求获取文件流
        const response = await this.$http({
          method: 'get',
          url: '/statistics/finance/receivable-payable/export',
          params: {
            startDate: params.startDate,
            endDate: params.endDate
          },
          responseType: 'blob', // 重要：指定响应类型为blob
          headers: {
            'Content-Type': 'application/json;charset=UTF-8'
          }
        })

        // 创建下载链接
        const url = window.URL.createObjectURL(new Blob([response.data]))
        const link = document.createElement('a')
        link.href = url

        // 尝试从响应头获取文件名
        let fileName = '应收应付明细.xlsx'
        const disposition = response.headers && response.headers['content-disposition']

        if (disposition && disposition.indexOf('attachment') !== -1) {
          const filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/
          const matches = filenameRegex.exec(disposition)
          if (matches != null && matches[1]) {
            fileName = matches[1].replace(/['"]/g, '')
          }
        }

        // 设置下载属性并触发下载
        link.setAttribute('download', fileName)
        document.body.appendChild(link)
        link.click()

        // 清理
        setTimeout(() => {
          document.body.removeChild(link)
          window.URL.revokeObjectURL(url)
          this.$message.success('导出成功，文件下载中...')
        }, 100)
      } catch (error) {
        console.error('导出失败:', error)
        this.$message.error('导出失败: ' + (error.message || '未知错误'))
      } finally {
        this.exportLoading = false
      }
    },

    flattenTreeData(treeData) {
      const result = []

      const flatten = (nodes, level = 0) => {
        nodes.forEach((node) => {
          const flatNode = { ...node, level }
          delete flatNode.children
          result.push(flatNode)

          if (node.children && node.children.length > 0) {
            flatten(node.children, level + 1)
          }
        })
      }

      flatten(treeData)
      return result
    }
  },
}
</script>

<style lang="less" scoped>
.receivable-payable-tree {
  background: #f5f7fa;
  min-height: 100vh;
  padding: 16px;
}

.page-container {
  max-width: 1400px;
  margin: 0 auto;
}

.page-header {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border-radius: 16px;
  padding: 24px 32px;
  margin-bottom: 24px;
  box-shadow: 0 8px 32px rgba(102, 126, 234, 0.15);

  .header-content {
    display: flex;
    justify-content: space-between;
    align-items: center;

    .page-title {
      font-size: 28px;
      font-weight: 600;
      color: #ffffff;
      margin: 0;
      text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
    }

    .header-actions {
      display: flex;
      align-items: center;
      gap: 12px;

      .ant-btn-primary {
        background: rgba(255, 255, 255, 0.2);
        border: 1px solid rgba(255, 255, 255, 0.3);
        border-radius: 8px;
        font-weight: 500;
        backdrop-filter: blur(10px);
        transition: all 0.3s ease;

        &:hover {
          background: rgba(255, 255, 255, 0.3);
          border-color: rgba(255, 255, 255, 0.5);
          transform: translateY(-1px);
        }
      }

      .ant-btn:not(.ant-btn-primary) {
        background: rgba(255, 255, 255, 0.1);
        border: 1px solid rgba(255, 255, 255, 0.2);
        border-radius: 8px;
        color: #ffffff;
        font-weight: 500;
        backdrop-filter: blur(10px);
        transition: all 0.3s ease;

        &:hover {
          background: rgba(255, 255, 255, 0.2);
          border-color: rgba(255, 255, 255, 0.4);
          color: #ffffff;
          transform: translateY(-1px);
        }
      }

      .ant-calendar-picker {
        .ant-calendar-picker-input {
          background: rgba(255, 255, 255, 0.9);
          border: 1px solid rgba(255, 255, 255, 0.3);
          border-radius: 8px;
          backdrop-filter: blur(10px);

          &:hover {
            border-color: rgba(255, 255, 255, 0.5);
          }
        }
      }
    }
  }
}

.summary-cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
  margin-bottom: 24px;
}

.summary-card {
  background: #ffffff;
  border-radius: 12px;
  padding: 24px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
  display: flex;
  align-items: center;
  transition: all 0.3s ease;

  &:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
  }

  .card-icon {
    width: 48px;
    height: 48px;
    border-radius: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-right: 16px;
    font-size: 20px;
    color: #ffffff;
  }

  &.receivable .card-icon {
    background: linear-gradient(135deg, #1890ff, #36cfc9);
  }

  &.payable .card-icon {
    background: linear-gradient(135deg, #f5222d, #fa8c16);
  }

  &.balance .card-icon {
    background: linear-gradient(135deg, #52c41a, #73d13d);
  }

  .card-content {
    flex: 1;

    .card-title {
      font-size: 14px;
      color: #666;
      margin-bottom: 8px;
    }

    .card-value {
      font-size: 24px;
      font-weight: 600;
      color: #303133;
      margin-bottom: 4px;

      &.positive {
        color: #52c41a;
      }

      &.negative {
        color: #f5222d;
      }

      &.neutral {
        color: #666;
      }
    }

    .card-detail {
      font-size: 12px;
      color: #999;
    }
  }
}

.content-tabs {
  background: #ffffff;
  border-radius: 12px;
  padding: 24px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}

.tree-table-container {
  .table-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 16px;

    h3 {
      font-size: 16px;
      font-weight: 600;
      color: #303133;
      margin: 0;
    }

    .table-actions {
      display: flex;
      gap: 8px;
    }
  }
}

.amount-text {
  font-weight: 500;

  &.receivable {
    color: #1890ff;
  }

  &.received {
    color: #52c41a;
  }

  &.unreceived {
    color: #fa8c16;
  }

  &.payable {
    color: #f5222d;
  }
}

.node-customer {
  font-weight: 600;
  color: #1890ff;
}

.node-project {
  font-weight: 500;
  color: #52c41a;
  margin-left: 16px;
}

.node-order {
  color: #666;
  margin-left: 32px;
}

.node-supplier {
  font-weight: 600;
  color: #f5222d;
}

.node-purchase_order {
  font-weight: 500;
  color: #fa8c16;
  margin-left: 16px;
}

.node-purchase_detail {
  color: #666;
  margin-left: 32px;
}

@media (max-width: 1200px) {
  .summary-cards {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 768px) {
  .page-header .header-content {
    flex-direction: column;
    gap: 16px;
    align-items: flex-start;
  }

  .summary-card {
    flex-direction: column;
    text-align: center;

    .card-icon {
      margin-right: 0;
      margin-bottom: 16px;
    }
  }
}
</style>
